package com.fly.demo.controller;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fly.common.exception.DataException;
import com.fly.common.utils.AnnotationHelper;
import com.fly.demo.entity.FileEntity;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * IndexController
 * 
 * @author 00fly
 * @version [版本号, 2018-11-06]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
@Api(tags = "演示接口")
@Controller
public class IndexController
{
    @Autowired
    ApplicationContext applicationContext;
    
    /**
     * 首页
     * 
     * @param model
     * @return
     * @throws Exception
     * @see [类、类#方法、类#成员]
     */
    @RequestMapping("/")
    public String index(Model model)
        throws Exception
    {
        model.addAttribute("urls", AnnotationHelper.getRequestMappingURL(applicationContext));
        return "index";
    }
    
    /**
     * 使用FileEntity必须做到<br>
     * 1.mvc配置multipartResolver<br>
     * 2.引入commons-fileupload
     * 
     * @param data
     * @see [类、类#方法、类#成员]
     */
    @ApiOperation("文件上传")
    @PostMapping(value = "/upload", consumes = "multipart/form-data")
    public void upload(FileEntity data)
    {
        if (data.getImage() == null)
        {
            throw new DataException("文件不能为空");
        }
    }
    
    /**
     * 使用MultipartHttpServletRequest必须做到<br>
     * 1.mvc配置multipartResolver<br>
     * 2.引入commons-fileupload
     * 
     * @param request
     * @see [类、类#方法、类#成员]
     */
    @ApiOperation("文件上传2")
    @ResponseBody
    @PostMapping(value = "/upload2")
    public String upload2(HttpServletRequest request)
    {
        if (request instanceof MultipartHttpServletRequest)
        {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
            MultipartFile file = multipartRequest.getFile("image");
            String userName = multipartRequest.getParameter("userName");
            FileEntity data = new FileEntity().setImage(file).setUserName(userName);
            log.info("data: {}", data);
            return "success";
        }
        return "failure";
    }
    
    @ApiOperation(value = "文件下载")
    @GetMapping(value = "/down", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void down(HttpServletResponse response)
        throws IOException
    {
        List<Path> filePaths = new ArrayList<>();
        Stream.of(new ClassPathResource("pic").getFile().listFiles()).forEach(lib -> filePaths.add(lib.toPath()));
        
        // 压缩多个文件到zip文件中
        String filename = DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMddHHmmss");
        response.setHeader("Content-Disposition", "attachment;filename=imgs_" + filename + ".zip");
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream()))
        {
            for (Path path : filePaths)
            {
                try (InputStream inputStream = Files.newInputStream(path))
                {
                    zipOutputStream.putNextEntry(new ZipEntry(path.getFileName().toString()));
                    StreamUtils.copy(inputStream, zipOutputStream);
                    zipOutputStream.flush();
                }
            }
        }
    }
}
